import { HeaderComponent } from "./header.js"
import { requests } from "../utils/request.js"
import { loadingRef, createLoad, hideLoad, hideEmpty, createEmpty,previewImg } from "../utils/utils.js"
import { Tooltip } from "../utils/tooltip.js"
//DOMContentLoaded：解析完脚本文件后执行
window.addEventListener('DOMContentLoaded', function () {
    const header = new HeaderComponent()
    const page = new ComponentPage(header)
    header.languageFn = page.createMenu.bind(page)
    page.createMenu()
    new Tooltip()
})
class ComponentPage {
    static name = "component-page"

    /* #-私有变量 */
    #query = new URLSearchParams(location.search);//路由参数对象
    #menuList = {}//左侧组件菜单列表
    #activeKey = ""//菜单选中key
    #activeData = null//当前展示组件数据
    #menuClassName = "component-page-container-menu-list-li"//菜单项classname
    #menuActiveClassName = "component-page-container-menu-list-active"//菜单项active classname
    #componentBoxClassName = "component-page-container-info-custom"//组件生成classname
    #componentBoxDom = document.getElementsByClassName(this.#componentBoxClassName)[0]//组件生成dom
    #loading = loadingRef(false, createLoad, hideLoad)
    #tableHead = ["参数", "说明", "类型", "默认值"]//API头部
    #codeTitle = { "CN": "代码演示", "EN": "Code demonstration" }
    #header = {}//header组件实例
    constructor(header) {
        this.#header = header
    }
    createMenu() {//创建左侧组件菜单
        this.#loading.value = true
        this.#getComponentMenu().then(res => {
            this.#menuList = res.COMPONENT_MENU
            const box = document.getElementsByClassName("component-page-container-menu-list")[0]
            box.innerHTML = ""
            box.onclick = this.#menuClickHandle.bind(this)//事件委托
            this.#menuList.forEach((item, index) => {
                const li = document.createElement("li")
                li.setAttribute("data-key", item.key)
                li.setAttribute("class", this.#menuClassName)
                const name = `
                <span data-key="${item.key}" class="component-page-container-menu-list-li-key">${item.key}</span>
                <span data-key="${item.key}" class="component-page-container-menu-list-li-title">${item.title}</span>
            `
                li.innerHTML = name
                li.setAttribute('data-key', item.key)
                box.appendChild(li)
            })
            this.#activeKey = this.#query.get("key") || this.#menuList[0].key
            this.#menuActiveStyleHandle(this.#activeKey)
            this.#createComponentContainer()
        })
    }
    #getComponentMenu() {//获取组件菜单
        return requests.get(`/data/component/${this.#header.languageKey}/config/menu.json`)
    }
    #getComponent() {//获取组件
        return import(`/data/component/${this.#header.languageKey}/${this.#activeKey}.js`)
    }
    #getComponentController() {//获取组件操作按钮配置
        return requests.get(`/data/component/${this.#header.languageKey}/config/code-btn-list.json`)
    }
    #menuActiveStyleHandle(key) {//菜单选中样式处理
        const className = `${this.#menuClassName} ${this.#menuActiveClassName}`
        Array.from(document.getElementsByClassName(this.#menuClassName)).forEach(item => {
            if (item.getAttribute("data-key") === key) {
                item.setAttribute("class", className)
            } else if (item.getAttribute("class") === className) {
                item.setAttribute("class", `${this.#menuClassName}`)
            }
        })
    }
    #menuClickHandle(e) {//菜单点击处理
        const key = e.target.getAttribute('data-key')
        if (key) {
            this.#activeKey = key
            const url = new URL(location)
            url.searchParams.set("key", key)
            history.pushState({}, "", url)
            this.#menuActiveStyleHandle(this.#activeKey)
            this.#createComponentContainer()
            //切换滚动回顶部
            window.scrollTo({top:0})
        }
    }
    #previewImgHandler(e) {//预览图片处理
        const url = e.target.getAttribute('data-url')
        const isOpen = e.target.getAttribute('data-open')
        if (url && isOpen === "true") {
            previewImg(url)
        }
    }
    #componentClickHandle(e) {//组件展示区域点击事件处理
        const nodeName = e.target.nodeName//点击节点名称
        if (nodeName === 'IMG') {
            if (e.target.getAttribute('code-btn-index') != null) {
                this.#codeBtnClickHandler(e.target)
            } else {
                this.#previewImgHandler(e)
            }
        }
    }
    #codeBtnClickHandler(e) {//代码按钮点击处理
        const index = e.getAttribute('code-btn-index')
        const type = e.getAttribute("code-btn-type")
        const codeBox = document.getElementsByClassName("language-javascript")[index]
        const wrapper = document.getElementsByClassName("code-highlight-wrapper")[index]
        const data = this.#activeData.CODEList[index]
        switch (type) {
            case "code-vue": this.#codeShowHandler(wrapper, codeBox, data.vueHTML, { index, type, data }); break;
            case "copy-vue": this.#codeCopyHandler(e, data.vueCode); break;
            case "code-react": this.#codeShowHandler(wrapper, codeBox, data.reactHTML, { index, type, data }); break;
            case "copy-react": this.#codeCopyHandler(e, data.reactCode); break;
        }
    }
    #codeCopyHandler(e, code) {//代码复制处理
        const def = e.getAttribute("src")
        const textarea = document.createElement('textarea');
        textarea.value = code;
        // 将 textarea 添加到文档中
        document.body.appendChild(textarea);

        // 选择 textarea 中的文本
        textarea.select();
        textarea.setSelectionRange(0, 99999); // 对于移动设备
        // 执行复制命令
        document.execCommand('copy');
        // 移除临时 textarea
        document.body.removeChild(textarea);
        const img = e.getAttribute("code-btn-sure")
        if (img) {
            //展示成功图标，延迟2秒复原。
            e.setAttribute("src", `../static/images/${img}.png`)
            setTimeout(() => {
                e.setAttribute("src", def)
            }, 1500)
        }
    }
    #codeShowHandler(wrapper, code, HTML, { index, type, data }) {//代码展示处理
        const wType = wrapper.getAttribute("data-type", type)
        if (data[type]) {
            if (wType !== type) {
                wrapper.style.display = 'block'
                code.innerHTML = HTML
            } else {
                wrapper.style.display = 'none'
                code.innerHTML = ''
                data[type] = false
            }
        } else {
            wrapper.style.display = 'block'
            code.innerHTML = HTML
            data[type] = true
        }
        wrapper.setAttribute("data-type", type)
    }
    #createComponentContainer() {//创建组件展示内容
        Promise.allSettled([this.#getComponent(), this.#getComponentController()]).then(res => {
            const list = res.filter(item => item.status === "fulfilled")
            if (list.length ===2) {
                const data = list[0].value.data
                if (data&&data.CODEList) {
                    data.CODEList.forEach(item => {
                        item.btnList = list[1].value
                    })
                }
                
                this.#activeData = data
                const { CODEList, APIList, otherList } = this.#activeData
                this.#componentBoxDom.innerHTML = ''
                if (this.#activeData) {
                    hideEmpty()
                    //创建标题
                    this.#createComponentTitle(this.#activeData)
                    //创建代码演示内容
                    this.#createComponentCode(CODEList)
                    //创建API内容
                    this.#createAPIBox(APIList)
                    if (otherList && otherList.length > 0) {
                        //创建其他
                        this.#createOthersBox(otherList)
                    }
                    //创建跳转列表区域
                    this.#createLinkList(CODEList, otherList)
                    //展示区域点击事件
                    document.getElementsByClassName(this.#componentBoxClassName)[0].onclick = this.#componentClickHandle.bind(this)
                    setTimeout(() => {
                        // 延迟动画关闭，防止页面闪烁
                        this.#loading.value = false
                    }, 1000)
                } else {
                    this.#createLinkList()
                    createEmpty()
                    this.#loading.value = false
                }
            } else {
                this.#componentBoxDom.innerHTML = ''
                this.#createLinkList()
                createEmpty()
                this.#loading.value = false
            }
        })
    }
    #createComponentTitle(data) {//创建component标题区域
        const title = document.createElement("h1")
        title.innerText = data.title
        const titleText = document.createElement("section")
        titleText.setAttribute("class", "markdown")
        data.titleText.forEach(item => {
            const text = document.createElement("p")
            text.innerHTML = item
            titleText.appendChild(text)
        })
        this.#componentBoxDom.appendChild(title)
        this.#componentBoxDom.appendChild(titleText)
    }
    #codeImgHTML(data) {//代码图片HTML
        const box = document.createElement("div")
        box.setAttribute("class", "code-container-info")
        if (data.imgs) {
            //图片前缀
            const urlPrefix = `/static/images/${this.#activeKey}/`
            const imgs = data.imgs.map((item, index) => {//代码图片字符串
                let str = `<img
                        data-url=${urlPrefix + item.url}
                        data-open=${item.isOpen}
                        class=${item.isOpen ? 'allow-preview-img' : ''}
                        style="cursor:${item.isOpen ? 'pointer' : 'default'}"
                        title=${item.isOpen ? '点击预览' : item.title}
                        height=${item.height}
                        width=${item.width}
                        src=${urlPrefix + item.url}
                    />`
                if (index !== data.imgs.length - 1) {
                    str += '>'
                }
                return str
            }).join("")
            box.innerHTML = imgs
        }

        return box
    }
    #codeTitleHTML(data) {//代码标题HTML
        const box = document.createElement('div')
        box.setAttribute("class", "code-title markdown")
        box.innerHTML = `
                <span class="code-title-text">${data.title}</span>
                <div>
                    <span class="code-title-introduction">${data.introduction}</span>
                </div>
                ${data.attention ? `
                <div class=code-title-attention>
                    <span>${data.attention}</span>
                </div>
                `: ""}
            `
        return box
    }
    #codeBtnHTML(data, index) {//代码操作按钮HTML
        const box = document.createElement('div')
        box.setAttribute("class", "code-btn")
        data.hiddenCode = data.hiddenCode ? data.hiddenCode : []
        if (data.btnList) {
            data.btnList.forEach(item => {//下方操作按钮字符串
                const tf = data.hiddenCode.some(citem => item.type.includes(citem))
                if (!tf) {
                    const img = document.createElement('img')
                    const defUrl = `../static/images/${item.img}.png`
                    img.setAttribute("src", defUrl)
                    img.setAttribute("code-btn-index", index)
                    img.setAttribute("code-btn-sure", item.clickImg)
                    img.setAttribute("code-btn-type", item.type)
                    img.setAttribute("tooltip-text", item.text)
                    img.setAttribute("tooltip-popover", item.isTooltip ? "true" : "false")
                    if (item.hoverImg) {
                        const activeUrl = `../static/images/${item.hoverImg}.png`
                        imgHoverChange({
                            target: img,
                            defUrl,
                            activeUrl
                        })
                    }
                    box.appendChild(img)
                }

            })
        }
        return box
    }
    #codeShowHTML(data) {//代码展示HTML
        const box = document.createElement('div')
        box.setAttribute("class", "code-highlight-wrapper markdown")
        box.setAttribute("style", "display:none")
        box.innerHTML = "<code class=language-javascript></code>"
        return box
    }
    #codeBoxHTML(data, index) {//代码演示项HTML
        const box = document.createElement('div')
        const imgs = this.#codeImgHTML(data)//代码项展示图片
        const title = this.#codeTitleHTML(data)//代码项标题
        const btns = this.#codeBtnHTML(data, index)//代码项底部操作按钮
        const code = this.#codeShowHTML(data)//代码展示
        box.appendChild(imgs)
        box.appendChild(title)
        box.appendChild(btns)
        box.appendChild(code)
        return box
    }
    #createOthersBox(list = []) {//创建其他
        if (list) {
            list.forEach(item => {
                const box = document.createElement('section')
                const title = document.createElement("h2")
                title.innerText = item.title
                box.appendChild(title)
                if (item.titleText) {
                    const titleText = document.createElement("section")
                    titleText.setAttribute("class", "markdown")
                    item.titleText.forEach(citem => {
                        const text = document.createElement("p")
                        text.innerText = citem
                        titleText.appendChild(text)
                    })
                    box.appendChild(titleText)
                }
                const head = item.header.map(item => `<th>${item}</th>`).join("")
                const body = item.list.map(bitem => {
                    //表列表内容
                    const td = Object.keys(bitem).map(citem => {
                        if(item.colorFields&&item.colorFields[citem]) {
                            return `<td style=color:${item.colorFields[citem]}>${bitem[citem]}</td>`
                        } else {
                            return `<td>${bitem[citem]}</td>`
                        }
                    }).join("")
                    return `<tr>${td}</tr>`
                }).join("")
                const table = document.createElement("table")
                table.setAttribute("class", "code-container api-table-container")
                table.innerHTML = `
                        <thead>
                            ${head}
                        </thead>
                        <tbody>
                            ${body}
                        </tbody>
                `
                box.appendChild(table)
                this.#componentBoxDom.appendChild(box)
            })
        }
    }
    #createAPIBox(list) {//创建API项
        if (list) {
            const box = document.createElement('section')
            const title = document.createElement("h2")
            title.innerText = "API"
            box.appendChild(title)
            const head = this.#tableHead.map(item => `<th>${item}</th>`).join("")
            const body = list.map(item => {
                const td = Object.keys(item).map(citem => `<td class=${citem === 'type' ? 'code' : ''}>${item[citem]}</td>`).join("")
                return `<tr>${td}</tr>`
            }).join("")
            const table = document.createElement("table")
            table.setAttribute("class", "code-container api-table-container")
            table.innerHTML = `
                    <thead>
                        ${head}
                    </thead>
                    <tbody>
                        ${body}
                    </tbody>
                `
            box.appendChild(table)
            this.#componentBoxDom.appendChild(box)
        }

    }
    #createComponentCode(list) {//创建component代码区域
        const title = document.createElement("h2")
        title.innerText = this.#codeTitle[this.#header.languageKey]
        this.#componentBoxDom.appendChild(title)
        if (list) {
            list.forEach((item, index) => {
                const section = document.createElement("section")
                section.setAttribute("class", "code-container")
                const code = this.#codeBoxHTML(item, index)
                section.appendChild(code)
                this.#componentBoxDom.appendChild(section)
            })
        }

    }
    #createLinkList(list = [], otherList = []) {//创建右边跳转滚动列表
        const ul = document.getElementsByClassName("code-link-list")[0]
        let newList = JSON.parse(JSON.stringify(list))
        if (list.length > 0) {
            newList.push({ title: "API" })
        }
        newList = newList.concat(otherList)
        ul.innerHTML = ""
        if (newList && newList.length > 0) {
            newList.forEach((item, index) => {
                const li = document.createElement("li")
                li.setAttribute("class", "ellipsis")
                li.setAttribute("title", item.title)
                li.innerText = item.title
                li.onclick = () => {
                    const element = document.getElementsByClassName("code-container")[index];
                    //滚动到元素区域
                    element.scrollIntoView({ behavior: 'smooth' });
                }
                ul.appendChild(li)
            })
        }
    }
}

